using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Timers;
using System.Windows.Forms;

namespace demo
{
    /// <summary>
    /// 壁纸自动切换管理器
    /// 提供自动切换系统桌面壁纸的功能
    /// </summary>
    public class WallpaperSlideshow : IDisposable
    {
        #region Win32 API
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);

        // 定义常量
        private const int SPI_SETDESKWALLPAPER = 20;
        private const int SPIF_UPDATEINIFILE = 0x01;
        private const int SPIF_SENDWININICHANGE = 0x02;
        #endregion

        #region 私有字段
        // 存储图片路径的数组
        private string[] imagePaths;

        // 当前图片索引
        private int currentIndex = 0;

        // 定时器
        private System.Timers.Timer timer;

        // 图片文件夹路径
        private string backgroundDirectory;

        // 切换间隔（毫秒）
        private double intervalMilliseconds;

        // 是否已释放资源
        private bool disposed = false;

        // 用于UI线程调用的控件引用
        private Control uiControl;
        #endregion

        #region 事件
        /// <summary>
        /// 壁纸切换事件
        /// </summary>
        public event EventHandler<WallpaperChangedEventArgs> WallpaperChanged;

        /// <summary>
        /// 错误发生事件
        /// </summary>
        public event EventHandler<WallpaperErrorEventArgs> ErrorOccurred;
        #endregion

        #region 构造函数
        /// <summary>
        /// 初始化壁纸切换器
        /// </summary>
        /// <param name="uiControl">用于UI线程调用的控件（通常是主窗体）</param>
        /// <param name="backgroundDirectory">壁纸图片文件夹路径，如果为空则使用程序目录下的background文件夹</param>
        /// <param name="intervalMinutes">切换间隔（分钟），默认10分钟</param>
        public WallpaperSlideshow(Control uiControl, string backgroundDirectory = null, double intervalMinutes = 10)
        {
            this.uiControl = uiControl ?? throw new ArgumentNullException(nameof(uiControl));
            this.backgroundDirectory = backgroundDirectory ?? Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "background");
            this.intervalMilliseconds = intervalMinutes * 60 * 1000; // 转换为毫秒
        }
        #endregion

        #region 公共属性
        /// <summary>
        /// 获取或设置切换间隔（分钟）
        /// </summary>
        public double IntervalMinutes
        {
            get { return intervalMilliseconds / (60 * 1000); }
            set
            {
                if (value <= 0)
                    throw new ArgumentException("切换间隔必须大于0", nameof(value));
                
                intervalMilliseconds = value * 60 * 1000;
                
                // 如果定时器正在运行，重新设置间隔
                if (timer != null && timer.Enabled)
                {
                    timer.Interval = intervalMilliseconds;
                }
            }
        }

        /// <summary>
        /// 获取当前是否正在运行
        /// </summary>
        public bool IsRunning => timer != null && timer.Enabled;

        /// <summary>
        /// 获取图片总数
        /// </summary>
        public int ImageCount => imagePaths?.Length ?? 0;

        /// <summary>
        /// 获取当前图片索引
        /// </summary>
        public int CurrentIndex => currentIndex;

        /// <summary>
        /// 获取当前图片路径
        /// </summary>
        public string CurrentImagePath => (imagePaths != null && imagePaths.Length > 0) ? imagePaths[currentIndex] : null;
        #endregion

        #region 公共方法
        /// <summary>
        /// 启动壁纸自动切换
        /// </summary>
        /// <returns>启动结果</returns>
        public WallpaperResult Start()
        {
            try
            {
                // 检查文件夹是否存在
                if (!Directory.Exists(backgroundDirectory))
                {
                    var errorMsg = $"未找到background文件夹: {backgroundDirectory}";
                    OnErrorOccurred(new WallpaperErrorEventArgs(errorMsg, new DirectoryNotFoundException(errorMsg)));
                    return new WallpaperResult { Success = false, ErrorMessage = errorMsg };
                }

                // 获取所有JPG和PNG图片文件
                imagePaths = Directory.GetFiles(backgroundDirectory, "*.jpg")
                            .Concat(Directory.GetFiles(backgroundDirectory, "*.jpeg"))
                            .Concat(Directory.GetFiles(backgroundDirectory, "*.png"))
                            .Concat(Directory.GetFiles(backgroundDirectory, "*.bmp"))
                            .ToArray();

                if (imagePaths.Length == 0)
                {
                    var errorMsg = "background文件夹中未找到图片文件!";
                    OnErrorOccurred(new WallpaperErrorEventArgs(errorMsg, null));
                    return new WallpaperResult { Success = false, ErrorMessage = errorMsg };
                }

                // 初始化定时器
                timer = new System.Timers.Timer(intervalMilliseconds);
                timer.Elapsed += Timer_Elapsed;
                timer.AutoReset = true;
                timer.Enabled = true;

                // 首次设置壁纸
                ChangeWallpaper();

                return new WallpaperResult { Success = true, ErrorMessage = null };
            }
            catch (Exception ex)
            {
                var errorMsg = $"启动壁纸切换时发生错误: {ex.Message}";
                OnErrorOccurred(new WallpaperErrorEventArgs(errorMsg, ex));
                return new WallpaperResult { Success = false, ErrorMessage = errorMsg };
            }
        }

        /// <summary>
        /// 停止壁纸自动切换
        /// </summary>
        public void Stop()
        {
            if (timer != null)
            {
                timer.Stop();
                timer.Dispose();
                timer = null;
            }
        }

        /// <summary>
        /// 手动切换到下一张壁纸
        /// </summary>
        /// <returns>切换结果</returns>
        public WallpaperResult NextWallpaper()
        {
            try
            {
                if (imagePaths == null || imagePaths.Length == 0)
                {
                    var errorMsg = "没有可用的壁纸图片";
                    return new WallpaperResult { Success = false, ErrorMessage = errorMsg };
                }

                ChangeWallpaper();
                return new WallpaperResult { Success = true, ErrorMessage = null };
            }
            catch (Exception ex)
            {
                var errorMsg = $"切换壁纸时发生错误: {ex.Message}";
                OnErrorOccurred(new WallpaperErrorEventArgs(errorMsg, ex));
                return new WallpaperResult { Success = false, ErrorMessage = errorMsg };
            }
        }

        /// <summary>
        /// 手动切换到上一张壁纸
        /// </summary>
        /// <returns>切换结果</returns>
        public WallpaperResult PreviousWallpaper()
        {
            try
            {
                if (imagePaths == null || imagePaths.Length == 0)
                {
                    var errorMsg = "没有可用的壁纸图片";
                    return new WallpaperResult { Success = false, ErrorMessage = errorMsg };
                }

                // 向前移动索引
                currentIndex = (currentIndex - 1 + imagePaths.Length) % imagePaths.Length;
                
                // 设置壁纸
                string imagePath = imagePaths[currentIndex];
                SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, imagePath, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
                
                // 触发事件
                OnWallpaperChanged(new WallpaperChangedEventArgs(imagePath));
                
                return new WallpaperResult { Success = true, ErrorMessage = null };
            }
            catch (Exception ex)
            {
                var errorMsg = $"切换壁纸时发生错误: {ex.Message}";
                OnErrorOccurred(new WallpaperErrorEventArgs(errorMsg, ex));
                return new WallpaperResult { Success = false, ErrorMessage = errorMsg };
            }
        }

        /// <summary>
        /// 设置指定的壁纸
        /// </summary>
        /// <param name="imagePath">图片路径</param>
        /// <returns>设置结果</returns>
        public WallpaperResult SetWallpaper(string imagePath)
        {
            try
            {
                if (string.IsNullOrEmpty(imagePath) || !File.Exists(imagePath))
                {
                    var errorMsg = "指定的图片文件不存在";
                    return new WallpaperResult { Success = false, ErrorMessage = errorMsg };
                }

                // 调用 SystemParametersInfo 函数设置桌面壁纸
                SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, imagePath, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
                
                OnWallpaperChanged(new WallpaperChangedEventArgs(imagePath));
                return new WallpaperResult { Success = true, ErrorMessage = null };
            }
            catch (Exception ex)
            {
                var errorMsg = $"设置壁纸时发生错误: {ex.Message}";
                OnErrorOccurred(new WallpaperErrorEventArgs(errorMsg, ex));
                return new WallpaperResult { Success = false, ErrorMessage = errorMsg };
            }
        }

        /// <summary>
        /// 重新加载图片文件夹
        /// </summary>
        /// <returns>重新加载结果</returns>
        public WallpaperResult ReloadImages()
        {
            try
            {
                // 重新扫描图片文件
                if (Directory.Exists(backgroundDirectory))
                {
                    imagePaths = Directory.GetFiles(backgroundDirectory, "*.jpg")
                                .Concat(Directory.GetFiles(backgroundDirectory, "*.jpeg"))
                                .Concat(Directory.GetFiles(backgroundDirectory, "*.png"))
                                .Concat(Directory.GetFiles(backgroundDirectory, "*.bmp"))
                                .ToArray();

                    // 重置索引
                    currentIndex = 0;

                    return new WallpaperResult { Success = true, ErrorMessage = null };
                }
                else
                {
                    var errorMsg = $"图片文件夹不存在: {backgroundDirectory}";
                    return new WallpaperResult { Success = false, ErrorMessage = errorMsg };
                }
            }
            catch (Exception ex)
            {
                var errorMsg = $"重新加载图片时发生错误: {ex.Message}";
                OnErrorOccurred(new WallpaperErrorEventArgs(errorMsg, ex));
                return new WallpaperResult { Success = false, ErrorMessage = errorMsg };
            }
        }
        #endregion

        #region 私有方法
        private void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            // 使用Invoke确保在UI线程上执行
            if (uiControl.InvokeRequired)
            {
                uiControl.Invoke(new Action(ChangeWallpaper));
            }
            else
            {
                ChangeWallpaper();
            }
        }

        private void ChangeWallpaper()
        {
            try
            {
                if (imagePaths == null || imagePaths.Length == 0) return;

                // 获取当前要设置的图片路径
                string imagePath = imagePaths[currentIndex];

                // 调用 SystemParametersInfo 函数设置桌面壁纸
                SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, imagePath, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);

                // 触发壁纸切换事件
                OnWallpaperChanged(new WallpaperChangedEventArgs(imagePath));

                // 更新索引，循环遍历图片数组
                currentIndex = (currentIndex + 1) % imagePaths.Length;
            }
            catch (Exception ex)
            {
                var errorMsg = $"更换壁纸时发生错误: {ex.Message}";
                OnErrorOccurred(new WallpaperErrorEventArgs(errorMsg, ex));
            }
        }

        private void OnWallpaperChanged(WallpaperChangedEventArgs e)
        {
            WallpaperChanged?.Invoke(this, e);
        }

        private void OnErrorOccurred(WallpaperErrorEventArgs e)
        {
            ErrorOccurred?.Invoke(this, e);
        }
        #endregion

        #region IDisposable 实现
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {
                    Stop();
                }
                disposed = true;
            }
        }

        ~WallpaperSlideshow()
        {
            Dispose(false);
        }
        #endregion
    }

    #region 辅助类和事件参数
    /// <summary>
    /// 壁纸切换结果
    /// </summary>
    public class WallpaperResult
    {
        public bool Success { get; set; }
        public string ErrorMessage { get; set; }
    }

    /// <summary>
    /// 壁纸切换事件参数
    /// </summary>
    public class WallpaperChangedEventArgs : EventArgs
    {
        public string ImagePath { get; }
        public DateTime Timestamp { get; }

        public WallpaperChangedEventArgs(string imagePath)
        {
            ImagePath = imagePath;
            Timestamp = DateTime.Now;
        }
    }

    /// <summary>
    /// 壁纸错误事件参数
    /// </summary>
    public class WallpaperErrorEventArgs : EventArgs
    {
        public string ErrorMessage { get; }
        public Exception Exception { get; }
        public DateTime Timestamp { get; }

        public WallpaperErrorEventArgs(string errorMessage, Exception exception)
        {
            ErrorMessage = errorMessage;
            Exception = exception;
            Timestamp = DateTime.Now;
        }
    }
    #endregion
}